package org.example;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

public class QueryGenerator {

  // 定义时间格式
  private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

  public enum FieldType {
    TIME, NUMBER
  }

  public static List<String> generateQueries(String tableName, String fieldName,
                                             String startValue, String endValue,
                                             int splitCount, FieldType fieldType) {
    List<String> queries = new ArrayList<>();

    if (fieldType == FieldType.TIME) {
      // 处理时间字段
      LocalDateTime start = LocalDateTime.parse(startValue, formatter);
      LocalDateTime end = LocalDateTime.parse(endValue, formatter);

      long totalSeconds = ChronoUnit.SECONDS.between(start, end);
      long step = totalSeconds / splitCount;

      // 添加小于 startTime 的查询
      queries.add(String.format(
          "SELECT count(*) FROM %s WHERE %s < '%s';",
          tableName, fieldName, start.format(formatter)));

      // 分段查询
      for (int i = 0; i < splitCount; i++) {
        LocalDateTime currentStart = start.plusSeconds(step * i);
        LocalDateTime currentEnd = (i == splitCount - 1) ? end : currentStart.plusSeconds(step);

        String query = String.format(
            "SELECT count(*) FROM %s WHERE %s >= '%s' AND %s < '%s';",
            tableName,
            fieldName,
            currentStart.format(formatter),
            fieldName,
            currentEnd.format(formatter)
        );
        queries.add(query);
      }

      // 添加大于 endTime 的查询
      queries.add(String.format(
          "SELECT count(*) FROM %s WHERE %s > '%s';",
          tableName, fieldName, end.format(formatter)));

    } else if (fieldType == FieldType.NUMBER) {
      // 处理数字字段
      BigDecimal start = new BigDecimal(startValue);
      BigDecimal end = new BigDecimal(endValue);

      // 添加小于 startNumber 的查询
      queries.add(String.format(
          "SELECT count(*) FROM %s WHERE %s < '%s';",
          tableName, fieldName, start.toPlainString()));

      // 计算每个分割区间的跨度
      BigDecimal range = end.subtract(start);
      BigDecimal step = range.divide(BigDecimal.valueOf(splitCount), BigDecimal.ROUND_DOWN);

      // 分段查询
      for (int i = 0; i < splitCount; i++) {
        BigDecimal currentStart = start.add(step.multiply(BigDecimal.valueOf(i)));
        BigDecimal currentEnd = (i == splitCount - 1) ? end : currentStart.add(step).setScale(0, BigDecimal.ROUND_DOWN);

        String query = String.format(
            "SELECT count(*) FROM %s WHERE %s >= '%s' AND %s < '%s';",
            tableName,
            fieldName,
            currentStart.toPlainString(),
            fieldName,
            currentEnd.toPlainString()
        );
        queries.add(query);
      }

      // 添加大于 endNumber 的查询
      queries.add(String.format(
          "SELECT count(*) FROM %s WHERE %s > '%s';",
          tableName, fieldName, end.toPlainString()));
    }

    return queries;
  }

  // 生成 Oracle 分区建表语句
  public static String generatePartitionStatements(String tableName, String fieldName,
                                                   String startValue, String endValue,
                                                   int splitCount, FieldType fieldType) {
    StringBuilder partitionStatement = new StringBuilder();
    partitionStatement.append("PARTITION BY RANGE (").append(fieldName).append(") (\n");

    if (fieldType == FieldType.TIME) {
      // 处理时间字段
      LocalDateTime start = LocalDateTime.parse(startValue, formatter);
      LocalDateTime end = LocalDateTime.parse(endValue, formatter);

      long totalSeconds = ChronoUnit.SECONDS.between(start, end);
      long step = totalSeconds / splitCount;

      // 添加小于 startTime 的分区
      partitionStatement.append(String.format(
          "    PARTITION p_less_than_start VALUES LESS THAN (TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS')),\n",
          start.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
      ));

      // 分段分区
      for (int i = 0; i < splitCount; i++) {
        LocalDateTime currentEnd = (i == splitCount - 1) ? end : start.plusSeconds(step * (i + 1));
        partitionStatement.append(String.format(
            "    PARTITION p_%02d VALUES LESS THAN (TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS')),\n",
            i + 1,
            currentEnd.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        ));
      }

      // 添加大于 endTime 的分区
      partitionStatement.append(String.format(
          "    PARTITION p_greater_than_end VALUES LESS THAN (TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS')),\n",
          end.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
      ));

    } else if (fieldType == FieldType.NUMBER) {
      // 处理数字字段
      BigDecimal start = new BigDecimal(startValue);
      BigDecimal end = new BigDecimal(endValue);
      BigDecimal range = end.subtract(start);
      BigDecimal step = range.divide(BigDecimal.valueOf(splitCount), BigDecimal.ROUND_DOWN);

      // 添加小于 startNumber 的分区
      partitionStatement.append(String.format(
          "    PARTITION p_less_than_start VALUES LESS THAN (%s),\n",
          start.toPlainString()
      ));

      // 分段分区
      for (int i = 0; i < splitCount; i++) {
        BigDecimal currentEnd = (i == splitCount - 1) ? end : start.add(step.multiply(BigDecimal.valueOf(i + 1)));
        partitionStatement.append(String.format(
            "    PARTITION p_%02d VALUES LESS THAN (%s),\n",
            i + 1,
            currentEnd.toPlainString()
        ));
      }

      // 添加大于 endNumber 的分区
      partitionStatement.append(String.format(
          "    PARTITION p_greater_than_end VALUES LESS THAN (%s),\n",
          end.toPlainString()
      ));
    }

    partitionStatement.append("    PARTITION p_max VALUES LESS THAN (MAXVALUE)\n);\n");
    return partitionStatement.toString();
  }

  public static void main(String[] args) {
    // 示例参数：时间类型
    String tableName = "INPCASE.FRONT_SHEET@EMR_DBLINK";
    String fieldName = "create_time";
    String startTime = "20130101000000";
    String endTime = "20240101000000";
    int splitCount = 10;

    // 时间类型查询
    List<String> timeQueries = generateQueries(tableName, fieldName, startTime, endTime, splitCount, FieldType.TIME);
    timeQueries.forEach(System.out::println);

    // 生成 Oracle 分区建表语句
    String partitionStatement = generatePartitionStatements(tableName, fieldName, startTime, endTime, splitCount, FieldType.TIME);
    System.out.println(partitionStatement);
  }
}
